package com.biyao.core.config;


import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.Map;


/**
 * Created by 郑浩 on 2017/8/10.
 */

public abstract class AbstractDynamicDataSource <T extends DataSource> extends AbstractRoutingDataSource  implements ApplicationContextAware{



    /** 日志 */
  //  protected Logger logger = LoggerFactory.getLogger(getClass());
    /** 默认的数据源KEY */
    protected static final String DEFAULT_DATASOURCE_KEY = "defaultDataSource";

    /** 数据源KEY-VALUE键值对 */
    public Map<Object, Object> targetDataSources;

    /** spring容器上下文 */
    private static ApplicationContext ctx;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ctx = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return ctx;
    }

    public static Object getBean(String name) {
        return ctx.getBean(name);
    }


    public void setTargetDataSources(Map<Object, Object> targetDataSources) {
        this.targetDataSources = targetDataSources;
        super.setTargetDataSources(targetDataSources);
        // afterPropertiesSet()方法调用时用来将targetDataSources的属性写入resolvedDataSources中的
        super.afterPropertiesSet();
    }

    /**
     * 创建数据源
     * @param driverClassName 数据库驱动名称
     * @param url 连接地址
     * @param username 用户名
     * @param password 密码
     * @return 数据源{@link T}
     */
    public abstract T createDataSource(String driverClassName, String url, String username,
                                       String password);

    /**
     * 设置系统当前使用的数据源
     */
    @Override
    protected Object determineCurrentLookupKey() {

        Map<String, Object> configMap = DataSourceContextHolder.getDBType();
       // logger.info("【当前数据源配置为：{}】", configMap);
        System.out.println("【设置系统当前使用的数据源】"+configMap);
        if (configMap==null||"".equals(configMap)) {
            // 使用默认数据源
            return DEFAULT_DATASOURCE_KEY;
        }
        // 判断数据源是否需要初始化
        this.verifyAndInitDataSource();
        System.out.println("【切换至数据源：{}】"+configMap);
        return configMap.get(DataSourceContextHolder.DATASOURCE_KEY);
    }

    /**
     * 判断数据源是否需要初始化
     */
    private void verifyAndInitDataSource() {
        Map<String, Object> configMap = DataSourceContextHolder.getDBType();
        Object obj = this.targetDataSources.get(configMap.get(DataSourceContextHolder.DATASOURCE_KEY));
        if (obj != null) {
            return;
        }

        System.out.println("【初始化数据源】");
        T datasource = this.createDataSource(configMap.get(DataSourceContextHolder.DATASOURCE_DRIVER)
                        .toString(), configMap.get(DataSourceContextHolder.DATASOURCE_URL).toString(),
                configMap.get(DataSourceContextHolder.DATASOURCE_USERNAME).toString(),
                configMap.get(DataSourceContextHolder.DATASOURCE_PASSWORD).toString());
        this.addTargetDataSource(configMap.get(DataSourceContextHolder.DATASOURCE_KEY).toString(),
                datasource);
    }

    /**
     * 往数据源key-value键值对集合添加新的数据源
     */
    private void addTargetDataSource(String key, T dataSource) {
        this.targetDataSources.put(key, dataSource);
        super.setTargetDataSources(this.targetDataSources);
        // afterPropertiesSet()方法调用时用来将targetDataSources的属性写入resolvedDataSources中的
        super.afterPropertiesSet();
    }

}